import { createRoot } from "react-dom/client";
import Dialog from "../components/ui/Dialog";
import type { Root } from "react-dom/client";

export type DialogType = "info" | "warning" | "error" | "success";

interface DialogOptions {
  title: string;
  message: string;
  confirmText?: string;
  cancelText?: string;
  type?: DialogType;
}

/**
 * 全局对话框服务
 *
 * 用于在应用中的任何位置显示确认对话框，无需在每个组件中单独管理对话框状态
 * @author BelovedLYC
 */
class DialogService {
  private containerMap: Map<string, { container: HTMLElement; root: Root }> =
    new Map();
  private idCounter: number = 0;
  // 存储活跃对话框的选项，用于防止重复
  private activeDialogOptions: Map<string, boolean> = new Map();

  // 根据对话框选项生成唯一键
  private getDialogKey(options: DialogOptions): string {
    return `${options.type || "default"}:${options.title}:${options.message}`;
  }

  /**
   * 显示确认对话框
   * @param options 对话框选项
   * @returns Promise，确认时resolve为true，取消时resolve为false
   */
  confirm(options: DialogOptions): Promise<boolean> {
    // 检查是否已存在相同内容的对话框
    const dialogKey = this.getDialogKey(options);
    if (this.activeDialogOptions.has(dialogKey)) {
      console.log("对话框已存在，不重复创建:", dialogKey);
      // 如果已存在相同对话框，返回一个永远不会resolve的Promise
      // 这样调用者将等待现有对话框的结果
      return new Promise<boolean>(() => {
        // 什么都不做，等待现有对话框操作
      });
    }

    // 标记此对话框为活跃状态
    this.activeDialogOptions.set(dialogKey, true);
    console.log("创建新对话框:", dialogKey);

    return new Promise((resolve) => {
      const dialogId = `dialog-${++this.idCounter}`;

      // 创建容器元素
      const containerElement = document.createElement("div");
      containerElement.id = dialogId;
      document.body.appendChild(containerElement);

      // 创建React根节点
      const root = createRoot(containerElement);

      // 存储容器和根节点引用，以便后续清理
      this.containerMap.set(dialogId, {
        container: containerElement,
        root,
      });

      // 清理函数 - 负责卸载组件和移除DOM元素
      const cleanup = (result: boolean) => {
        console.log("执行清理:", dialogKey);

        // 卸载组件并移除DOM元素
        root.unmount();
        if (containerElement.parentNode) {
          containerElement.parentNode.removeChild(containerElement);
        }
        this.containerMap.delete(dialogId);

        // 解析Promise
        resolve(result);
      };

      // 关闭对话框并清理DOM
      const closeDialog = (result: boolean) => {
        const element = this.containerMap.get(dialogId);
        if (element) {
          console.log("关闭对话框:", dialogKey, "结果:", result);

          // 重要：立即从活跃对话框中移除，确保可以立即创建新的相同对话框
          // 不等待动画完成就移除，这样用户可以立即再次打开相同对话框
          this.activeDialogOptions.delete(dialogKey);
          console.log("对话框已从活跃列表中移除:", dialogKey);

          // 先将对话框状态设为关闭，触发动画
          root.render(
            <Dialog
              {...options}
              isOpen={false}
              onConfirm={() => {}}
              onCancel={() => {}}
              onClose={() => cleanup(result)}
            />
          );

          // 设置一个安全超时，确保即使动画或回调失败，也能清理资源
          setTimeout(() => {
            if (this.containerMap.has(dialogId)) {
              console.warn("对话框关闭动画超时，强制清理:", dialogKey);
              cleanup(result);
            }
          }, 1000); // 1秒后如果还没清理，强制清理
        } else {
          // 如果找不到元素，直接清理
          this.activeDialogOptions.delete(dialogKey);
          cleanup(result);
        }
      };

      // 渲染Dialog组件
      root.render(
        <Dialog
          {...options}
          isOpen={true}
          onConfirm={() => closeDialog(true)}
          onCancel={() => closeDialog(false)}
          onClose={() => {}} // 这个只在关闭动画结束后才会调用
        />
      );
    });
  }

  /**
   * 显示确认对话框（信息类型）
   */
  async info(options: Omit<DialogOptions, "type">): Promise<boolean> {
    return this.confirm({ ...options, type: "info" });
  }

  /**
   * 显示确认对话框（警告类型）
   */
  async warning(options: Omit<DialogOptions, "type">): Promise<boolean> {
    return this.confirm({ ...options, type: "warning" });
  }

  /**
   * 显示确认对话框（错误类型）
   */
  async error(options: Omit<DialogOptions, "type">): Promise<boolean> {
    return this.confirm({ ...options, type: "error" });
  }

  /**
   * 显示确认对话框（成功类型）
   */
  async success(options: Omit<DialogOptions, "type">): Promise<boolean> {
    return this.confirm({ ...options, type: "success" });
  }

  /**
   * 确认登出对话框
   * 提供快捷方法用于登出确认
   */
  async confirmLogout(): Promise<boolean> {
    return this.warning({
      title: "确认登出",
      message: "您确定要退出登录吗？",
      confirmText: "确认登出",
      cancelText: "取消",
    });
  }
}

// 创建单例实例
const dialogService = new DialogService();

export default dialogService;
